
package JET.Frames.DataModels;

import JET.Centers.ControlCenter;
import JET.Centers.Graphics.GUICenter;
import JET.Scene;
import JET.SceneHelper;
import JET.SceneItem;
import JET.SwingUtils.TreeUtil;
import JET.UtilPanels.UPSceneInspector;
import JET.UtilPanels.UPSceneItemsInspector;
import JET.physics.bodies.SpringBody;
import JET.physics.engine.*;
import JET.physics.interfaces.SceneTreeNode;
import java.util.ArrayList;
import javax.swing.JTree;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

/**
 *
 * @author 057Ry
 */
public class SceneItemsTreeModel  implements TreeModel {

    static final ControlCenter CC = ControlCenter.getInstance();
    public final SceneItemsRootNode sceneItemsRootNode = new SceneItemsRootNode();
    private Scene scene;
    private ArrayList<TreeModelListener> treeModelListeners = new ArrayList<TreeModelListener>();

    public SceneItemsTreeModel() {
    }

    public void setScene(Scene s) {
        scene = s;
    }

    public Object getRoot() {
        if (scene!=null)
            return sceneItemsRootNode;
        else
            return null;
    }

    public Object getChild(Object parent, int index) {
        if (scene!=null)
            return ((SceneTreeNode) parent).getChild(index);
        else
            return null;
    }

    public int getChildCount(Object parent) {
        if (scene!=null)
            return ((SceneTreeNode) parent).getChildCount();
        else
            return 0;
    }

    public boolean isLeaf(Object node) {
        if (scene!=null)
            return ((SceneTreeNode) node).isLeaf();
        else
            return true;
    }

    public void valueForPathChanged(TreePath path, Object newValue) {
        if (scene!=null)
            ((SceneTreeNode) path.getLastPathComponent()).resetNodeValue(newValue);
    }

    public int getIndexOfChild(Object parent, Object child) {
        if (scene!=null)
            return ((SceneTreeNode) parent).getIndexOfChild(child);
        else
            return -1;
    }

    ////////////////////////////////////////////////////////////////////////////
    //                            N O D E S                                   //
    ////////////////////////////////////////////////////////////////////////////

    public class SceneItemsRootNode implements SceneTreeNode {

        public SceneTreeNode getChild(int index) {
            return scene.sceneItemsList.get(index);
        }

        public int getChildCount() {
            return scene.sceneItemsList.size();
        }

        public boolean isLeaf() {
            return false;
        }

        public int getIndexOfChild(Object child) {
            return scene.sceneItemsList.indexOf(child);
        }

        public void resetNodeValue(Object o){}

        @Override
        public String toString() {
            return "SceneItems";
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //                T R E E   M O D E L   L I S T E N E R S                 //
    ////////////////////////////////////////////////////////////////////////////

    public void addTreeModelListener(TreeModelListener l) {
        treeModelListeners.add(l);
    }

    public void removeTreeModelListener(TreeModelListener l) {
        treeModelListeners.remove(l);
    }

    ////////////////////////////////////////////////////////////////////////////
    //                     N O T I F I C A T I O N S                          //
    ////////////////////////////////////////////////////////////////////////////

    public void fireSpringBodyChanged(SpringBody sb) {
        if (scene!=null) {
            SceneItem si = SceneHelper.getSceneItemThatOwnSpringBody(scene, sb);
            TreePath path = new TreePath(new Object[]{  sceneItemsRootNode,
                                                        si,
                                                        si.physicElementsNode,
                                                        si.springBodiesTreeNode,
                                                        sb
                                                     });

            JTree sceneItemsTree = ((UPSceneItemsInspector) CC.GUIC.getUtilTab(GUICenter.UtilTabs.SceneItemsInspector)).getSceneItemsTree();
            String sceneTreeExpansionState = TreeUtil.getExpansionState(sceneItemsTree, 0);

            TreeModelEvent evt = new TreeModelEvent(this, path);
            for(TreeModelListener l : treeModelListeners)
                l.treeStructureChanged(evt);

            TreeUtil.restoreExpanstionState(sceneItemsTree, 0, sceneTreeExpansionState);
        }
    }

    public void fireSpringItemChanged(SceneItem si) {
        if (scene!=null) {
            TreePath path = new TreePath(new Object[]{  sceneItemsRootNode,
                                                        si
                                                     });

            JTree sceneItemsTree = ((UPSceneItemsInspector) CC.GUIC.getUtilTab(GUICenter.UtilTabs.SceneItemsInspector)).getSceneItemsTree();
            String sceneTreeExpansionState = TreeUtil.getExpansionState(sceneItemsTree, 0);

            TreeModelEvent evt = new TreeModelEvent(this, path);
            for(TreeModelListener l : treeModelListeners)
                l.treeStructureChanged(evt);

            TreeUtil.restoreExpanstionState(sceneItemsTree, 0, sceneTreeExpansionState);
        }
    }

    public void fireSpringItemListChanged(SceneItem si) {
        if (scene!=null) {
            TreePath path = new TreePath(new Object[]{  sceneItemsRootNode,
                                                        si
                                                     });

            JTree sceneTree = ((UPSceneItemsInspector) CC.GUIC.getUtilTab(GUICenter.UtilTabs.SceneItemsInspector)).getSceneItemsTree();
            String sceneTreeExpansionState = TreeUtil.getExpansionState(sceneTree, 0);

            TreeModelEvent evt = new TreeModelEvent(this, path);
            for(TreeModelListener l : treeModelListeners)
                l.treeStructureChanged(evt);

            TreeUtil.restoreExpanstionState(sceneTree, 0, sceneTreeExpansionState);
        }
    }

    public void fireWholeTreeChanged() {
        if (scene!=null) {
            TreePath path = new TreePath(new Object[]{sceneItemsRootNode});

            JTree sceneTree = ((UPSceneInspector) CC.GUIC.getUtilTab(GUICenter.UtilTabs.SceneInspector)).getSceneTree();
            String sceneTreeExpansionState = TreeUtil.getExpansionState(sceneTree, 0);

            TreeModelEvent evt = new TreeModelEvent(this, path);
            for(TreeModelListener l : treeModelListeners)
                l.treeStructureChanged(evt);

            TreeUtil.restoreExpanstionState(sceneTree, 0, sceneTreeExpansionState);
        }
    }
}

